//this file define a timer to do schedule task
//mlcai 2011-06-13

#ifndef TIMER_H
#define TIMER_H

#include "NameSpaceDef.h"
#include ADD_QUOTE(INC_NAME_HEADER(NAMESPACE_NAME, Thread.h))

#include <map>
#include <list>

using std::multimap;
using std::map;
using std::list;

BEGIN_CXX_NAMESPACE_DEFINITION

class ScheduleProcessor;
class ScheProcessPool;
class DYNAMIC_API Timer
{
	friend class ScheProcessPool;
	friend class ScheduleProcessor;
public:
	virtual ~Timer();

	void start(long mseconds);
	void canncel();

protected:
	Timer();

	virtual void schedule() = 0;

private:
	volatile long m_scheduleTime;
	ScheProcessPool& m_schedulePool;
};

class ScheProcessPool
{
public:
	~ScheProcessPool();

	static ScheProcessPool& instance();

	void putTimer(Timer* timer);
	void deleteTimer(Timer* timer);

private:
	ScheProcessPool();
	static ScheProcessPool _scheProFac;

private:
	class ScheduleProcessor : public NAMESPACE_NAME::Thread
	{
	public:
		ScheduleProcessor(long waitUnitIv, long maxTaskSize = 10);
		virtual ~ScheduleProcessor();

		void addTimer(Timer* timer);
		
		bool removeTimer(Timer* timer);
		
		bool isTasksFull();

		bool isTasksEmpty();

		void stop();

	private:
		void run();
		NAMESPACE_NAME::Event m_waitor;
		long m_waitUnitIv;
		volatile bool m_isRunning;

	private:
		struct TimeTask
		{
			TimeTask() : m_timer(0)
			{
			}
			TimeTask(long scheduleTime, Timer* timer) :
			m_curRestTime(scheduleTime), m_timer(timer)
			{
			}
			TimeTask(const TimeTask& task)
			{
				m_curRestTime = task.m_curRestTime;
				m_timer = task.m_timer;
			}
			TimeTask& operator= (const TimeTask& task)
			{
				m_curRestTime = task.m_curRestTime;
				m_timer = task.m_timer;
				return *this;
			}
			long m_curRestTime;
			Timer* m_timer;
		};

		NAMESPACE_NAME::Mutex m_taskMutex;
		map<Timer*, TimeTask> m_timeTasks;
		volatile bool m_isTasksFull;
		volatile long m_maxTaskSize;
	};

private:
	ScheduleProcessor* getScheProcessor(long interval);
	long getScheUnitInterval(long interval);
	NAMESPACE_NAME::Mutex m_scheProceMutex;
	multimap<long, ScheduleProcessor*> m_scheProcessors;
};

END_CXX_NAMESPACE_DEFINITION

#endif
